var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var sassMiddleware = require('node-sass-middleware');
var bodyParser = require('body-parser');  // Middleware for parsing POST page requests

var db = require("../website/routes/database");   // Directly designating the same folder will be mistaken as a module
var userClass = require("../website/routes/userClass");

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(cookieParser());
app.use(sassMiddleware({
  src: path.join(__dirname, 'public'),
  dest: path.join(__dirname, 'public'),
  indentedSyntax: true, // true = .sass and false = .scss
  sourceMap: true
}));
app.use(express.static(path.join(__dirname, 'public')));

// Route control should be placed after the module reference, otherwise the form value cannot be obtained
var indexRouter = require('./routes/index');
var userCenterRouter = require('./routes/userCenter');
var userSettingRouter = require('./routes/userSetting');
var missionCenterRouter = require('./routes/missionCenter');
var loginRegisterRouter = require('./routes/loginRegister');
var usersRouter = require('./routes/users');

app.use('/', indexRouter);
app.use('/userCenter', userCenterRouter);
app.use('/userSetting', userSettingRouter);
app.use('/missionCenter', missionCenterRouter);
app.use('/loginRegister', loginRegisterRouter);
app.use('/users', usersRouter);

// Receive the return form, to be processed before the middleware function, otherwise data will be lost
app.use('/userSetting', (req, res) =>{
  console.log(req.body);
  console.log("userSetting Ajax Data received!");

  let postKey = Object.keys(req.body);
  let postValue = Object.values(req.body);

  // Note: There is no image file received in this form, please remember to solve
  global.interimUser.changeName = postValue[0];
  global.interimUser.password = postValue[1];
  global.interimUser.introduction = postValue[2];
  global.interimUser.permissions = postValue[3];
  global.interimUser.operating = "Modify";

  console.log(postValue);

  // Change user data
  db.query(
      "UPDATE USERS SET password = ?, username = ?, introduction = ?, permissions = ? WHERE username = ?",
      [
          global.interimUser.password,
          global.interimUser.changeName,
          global.interimUser.introduction,
          global.interimUser.name,
          global.interimUser.permissions
      ]
  );

  // Change temporary username
  global.interimUser.name = global.interimUser.changeName;
  global.interimUser.changeName = "";

});

app.use('/missionCenter', (req, res) =>{
    console.log(req.body);
    console.log("missionCenter Ajax Data received!");

    let postKey = Object.keys(req.body);
    let postValue = Object.values(req.body);

    global.interimTask.taskTitle = postValue[0];
    global.interimTask.taskDate = postValue[1];
    global.interimTask.taskContent = postValue[2];
    global.interimTask.taskPublisherGet = postValue[3];
    global.interimTask.taskPublisherSend = global.interimUser.name;

    // coding
    // Note that here is to add data to the form of the taskPublisher user,
    // and then add the user name of the task publisher to the taskPublisher of the taskPublisher user
    global.interimTask.taskTitleCode = db.coding(global.interimTask.taskTitle);
    global.interimTask.taskDateCode = db.coding(global.interimTask.taskDate);
    global.interimTask.taskContentCode = db.coding(global.interimTask.taskContent);
    global.interimTask.taskPublisherCode= db.coding(global.interimTask.taskPublisherSend);

    // Change user task data
    db.query(
        "UPDATE USERS SET taskTitle = CONCAT(IFNULL(taskTitle, ''), ?)," +
        " taskDate = CONCAT(IFNULL(taskDate, ''), ?)," +
        " taskContent = CONCAT(IFNULL(taskContent, ''), ?)," +
        " taskPublisher = CONCAT(IFNULL(taskPublisher, ''), ?)," +
        " taskNum = taskNum + 1 WHERE username = ?",
        [
            global.interimTask.taskTitleCode,
            global.interimTask.taskDateCode,
            global.interimTask.taskContentCode,
            global.interimTask.taskPublisherCode,

            global.interimTask.taskPublisherGet
        ]
    );

    // Record operation
    global.interimUser.operating = "Modify";

});

app.use('/loginRegister', (req, res) =>{
    console.log(req.body);
    console.log("loginRegister Ajax Data received!");

    // Data grouping
    let postKey = Object.keys(req.body);
    let postValue = Object.values(req.body);

    let loginPostKey = [];
    let loginPostValue = [];
    let registerPostKey = [];
    let registerPostValue = [];

    // Split form
    for (let i = 0; i < postKey.length; i++) {
        if (postKey[i] === 'userNameLogin' || postKey[i] === 'passWordLogin') {
            loginPostKey.push(JSON.parse(JSON.stringify(postKey[i])));
            loginPostValue.push(JSON.parse(JSON.stringify(postValue[i])));
        }
        else {
            registerPostKey.push(JSON.parse(JSON.stringify(postKey[i])));
            registerPostValue.push(JSON.parse(JSON.stringify(postValue[i])));
        }
    }

    // Determine whether the user's operation is login or registration
    if (loginPostValue[0] === ''){
        // registered
        global.interimUser.name = registerPostValue[0];
        global.interimUser.password = registerPostValue[1];
        global.interimUser.email = registerPostValue[3];
        global.operating = "Add";

        // Add users
        db.query(
            "INSERT INTO USERS(username, password, email) VALUES(?, ?, ?)",
            [
                global.interimUser.name,
                global.interimUser.password,
                global.interimUser.email,
            ]
        )
    }
    else if (registerPostValue[0] === ''){
        // Login
        global.interimUser.changeName = loginPostValue[0];
        global.interimUser.password = loginPostValue[1];
        global.operating = "Inquire";

        // Check if the user exists
        db.query(
            "SELECT * FROM USERS WHERE username = ?",
            [global.interimUser.changeName],
            function(results, fields) {
                if (results[0].username === global.interimUser.changeName){
                    // Update the temporary user table if it exists
                    global.interimUser.id = results[0].id;
                    global.interimUser.name = results[0].username;
                    global.interimUser.password = results[0].password;

                    let flag = false;
                    if (results[0].imageflag > 0){
                        flag = true;
                    }
                    global.interimUser.imageflag = flag;

                    global.interimUser.imagefile = "";
                    if (results[0].imagefile != null){
                        global.interimUser.imagefile = results[0].imagefile;
                    }

                    global.interimUser.permissions = results[0].permissions;
                    global.interimUser.introduction = results[0].introduction;
                    global.interimUser.email = results[0].email;
                    global.interimUser.taskNum = results[0].taskNum;

                    // Empty first and then load, otherwise there will be the problem of last user data retention
                    global.interimUser.taskTitle = [];
                    global.interimUser.taskContent = [];
                    global.interimUser.taskPublisher = [];
                    global.interimUser.taskDate = [];

                    db.decoding(global.interimUser, results[0].taskTitle, 1);
                    db.decoding(global.interimUser, results[0].taskContent, 2);
                    db.decoding(global.interimUser, results[0].taskPublisher, 3);
                    db.decoding(global.interimUser, results[0].taskDate, 4);

                    global.interimUser.changeName = "";
                    global.interimUser.operating = "Inquire";
                }
                else {
                    // Throw an exception to the page to let it prompt that the user was not found
                    throw "Can't Found Users!!!";
                }
            }
        )
    }
});

// 中间件函数
// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

// 设置访问时间上限
app.listen(5000, function () {
  console.log("Service Started");
});

module.exports = app;

// 定义全局变量
// 添加临时用户，用来代替 cookie 临时记录登录的用户
// 可以防止盗用 cookie 文件进行 xss 攻击
global.interimUser = {
  id : 0,
  imageflag : false,
  imagefile : "",
  name : "",
  changeName : "",
  password : "",
  permissions : "user",
  introduction : "",
  email : "",

  // 临时任务数据
  taskNum : 0,
  taskTitle : [],
  taskContent : [],
  taskPublisher : [],
  taskDate : [],

  // 存放操作标志，用来判断需要执行什么操作
  // 查：Inquire
  // 删：Delete
  // 增：Add
  // 改：Modify
  operating : ""
};

global.interimTask = {
  taskTitle: '',
  taskContent: '',
  taskDate: '',
  taskPublisherSend: '',
  taskPublisherGet: '',

  taskTitleCode : '',
  taskContentCode : '',
  taskPublisherCode : '',   // taskPublisherSend 的编码
  taskDateCode : '',

  taskNum : 0,
};

//---------数据库测试代码----------
// var mysql      = require('mysql');
// var connection = mysql.createConnection({
//   host     : 'localhost',
//   user     : 'root',
//   password : 'root',
//   database : 'TMR-app'
// });
//
// connection.connect();
//
// connection.query('SELECT * from users', function(err, data, fields) {
//   if (err) {
//     console.log(err);
//     return;
//   }
//
//   console.log(JSON.parse(JSON.stringify(data)));
// });
//
// connection.end();
